package smtp;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Store;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 * This class maintains a JList of IMAPFolders contained in an email account's default folder
 * It notifies a listener whenever a new selection occurs
 * 
 * @author chanderr, liw, wendlandts
 *
 */
public class MailBoxController {
	// list UI to display the folders
	private JList list= null;
	
	// list model containing the folders data
	private DefaultListModel listModel = null;
	
	// folderList received for the IMAPStore
	private Folder[] folderList=null;
	
	// Store connection to an email account
	private Store store=null;
	
	// listener to notify of selection changes
	private ActionListener listener;

	/**
	 * Constructor.
	 * 
	 * @param store - Store connection to an email account
	 * @param list - list to populate with folders from the Store
	 */
	public MailBoxController(Store store,final JList list) {
		this.store=store;
		this.list=list;
		this.listener = null;

		// Objects in the JList must be Folders and not a String representation
		// of them so that we can easily determine a selected value and do something with it
		list.setCellRenderer(new DefaultListCellRenderer(){

			public Component getListCellRendererComponent(JList list,
					Object obj, int index, boolean isSelected, boolean hasFocus) {
				
				// if the object to render is a folder, then let the default renderer call a
				// toString on a String representation of the folder
				
				// if the object is not a folder, then make no changes and render it as usual
				if(obj.getClass() == Folder.class){
					try {
						Folder folder = (Folder)obj;
						obj = new String(folder.getName()+'('+folder.getUnreadMessageCount()+'/'+folder.getMessageCount()+')');
					} catch (MessagingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}		

				return super.getListCellRendererComponent(list, obj, index, isSelected, hasFocus);
			}

		});

		// listen for a new selection and notify the action listener of it
		// the selected folder is set as the event's source
		list.addListSelectionListener(new ListSelectionListener(){

			@Override
			public void valueChanged(ListSelectionEvent event) {
				if(!(event.getValueIsAdjusting()) && (listener != null)){
					System.out.println("Recognized value change");
					listener.actionPerformed(new ActionEvent(list.getSelectedValue(), list.getSelectedIndex(), "New Folder Selected"));
				}

			}
		});
	}
	
	// Updates the JList with the store's default folder's folders
	public void updateJList(JList list){
		listModel = new DefaultListModel();
		try {
			// This list command mirrors IMAP's LIST command
			folderList = store.getDefaultFolder().list("*");
			for (Folder folder : folderList) {
				if ((folder.getType() & Folder.HOLDS_MESSAGES) != 0) {
					listModel.addElement(folder);
				}
			}
			// update the listModel
			// Don't want to create an entirely new JList because that will not replace the one displayed
			list.setModel(listModel);
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
	
	/**
	 * Unused.
	 * @param l
	 */
	public void addFocusListener(FocusListener l){
		FocusEvent e = new FocusEvent(list, 0);
		e.setSource(folderList);
		l.focusGained(e);


	}

	/**
	 * Replaces the listener that will be notified when a new folder is selected
	 * @param al
	 */
	public void addFolderChangeListener(ActionListener al){
		listener = al;
	}

	/**
	 * Returns the inbox of the Store.
	 * Used as a default to initialize the message list with
	 * 
	 * @return - Inbox folder
	 */
	public Folder getInbox(){
		Folder f=null;
		try {
			f=store.getFolder("INBOX");
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return f;
	}



}
